unit MLPArepAnalysis;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls, 
  Buttons, ExtCtrls, Dialogs,Printers, Mask, ComCtrls, Contnrs, Spin;
const
  PreviewMargin=5;

type
  TdlgPrintAnalysis = class(TForm)
    OKBtn: TButton;
    CancelBtn: TButton;
    Bevel1: TBevel;
    bvlPreview: TBevel;
    imgPreview: TImage;
    dlgPrint: TPrintDialog;
    btnPrinterSetup: TButton;
    Label1: TLabel;
    lblPrinterName: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    lblPageWidth: TLabel;
    lblPageHeight: TLabel;
    GroupBox1: TGroupBox;
    Label4: TLabel;
    Label5: TLabel;
    stHeaderFont: TStaticText;
    stBodytextFont: TStaticText;
    GroupBox2: TGroupBox;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    dlgFont: TFontDialog;
    udTopMargin: TUpDown;
    udBottomMargin: TUpDown;
    udLeftMargin: TUpDown;
    udRightMargin: TUpDown;
    lblTopMargin: TLabel;
    lblBottomMargin: TLabel;
    lblLeftMargin: TLabel;
    lblRightMargin: TLabel;
    seCurrentPage: TSpinEdit;
    Label10: TLabel;
    lblPageCount: TLabel;
    procedure FormResize(Sender: TObject);
    procedure btnPrinterSetupClick(Sender: TObject);
    procedure stHeaderFontClick(Sender: TObject);
    procedure stBodytextFontClick(Sender: TObject);
    procedure udTopMarginClick(Sender: TObject; Button: TUDBtnType);
    procedure seCurrentPageChange(Sender: TObject);
  private
    { Private declarations }
    Metafiles :TObjectlist;
    // Metafile : TMetafile;
    procedure UpdatePreview;
    procedure UpdateMetafile;
    procedure UpdatePreviewImage;
  public
    { Public declarations }
    procedure ShowPreviewDialog;
  end;

var
  dlgPrintAnalysis: TdlgPrintAnalysis;

implementation

uses MLPAOptions,MLPAMain;

{$R *.DFM}

procedure TdlgPrintAnalysis.FormResize(Sender: TObject);
begin
  // resize image too
  UpdatePreviewImage
end;

procedure TdlgPrintAnalysis.ShowPreviewDialog;
var
  i:integer;
begin
  stHeaderFont.Font.Assign(frmMLPAOptions.AnalysisHeaderfont);
  stBodytextFont.Font.Assign(frmMLPAOptions.AnalysisBodyFont);
  udTopMargin.Position:=frmMLPAOptions.AnalysisMarginTop;
  udBottomMargin.Position:=frmMLPAOptions.AnalysisMarginBottom;
  udLeftMargin.Position:=frmMLPAOptions.AnalysisMarginLeft;
  udRightMargin.Position:=frmMLPAOptions.AnalysisMarginRight;
  Metafiles:=TObjectList.Create;
  UpdatePreview;
  if ShowModal = mrOK then
  begin
    // Put metafile on currently selected printer
    Printer.BeginDoc;
    for i:=0 to Pred(Metafiles.Count) do
    begin
      Printer.Canvas.Draw(0,0,TMetafile(Metafiles[i]));
      if i<Pred(Metafiles.Count) then
        Printer.NewPage;
    end;
    Printer.EndDoc;
  end;
  Metafiles.Free;
end;

procedure TdlgPrintAnalysis.UpdateMetafile;
var
  Metafile : TMetafile;
  PrinterCanvas : TMetaFileCanvas;
  XScale:Double;
  PrintablePaper : TRect;
  CurrentCell : TRect;
  CurrentPos : TPoint;
  arow : integer;
  acol : integer;
  datacellwidth: integer;
  ppmmx : double;
  ppmmy : double;

  function FontLineHeight:integer;
  begin
    result:=Round(PrinterCanvas.TextHeight('Wj')* 1.25);
  end;

  procedure AddMetafile;
  begin
    PrinterCanvas.Free; // Freeing the canvas will copy it to originating Metafile
    Metafiles.Add(Metafile);
    MetaFile:=TMetaFile.Create;
    PrinterCanvas:=TMetaFileCanvas.Create(MetaFile,Printer.Handle);
    PrinterCanvas.FillRect(Rect(0,0,GetDeviceCaps(Printer.Handle,PHYSICALWIDTH),GetDeviceCaps(Printer.Handle,PHYSICALHEIGHT)));
    CurrentPos.y:=PrintablePaper.Top;
    PrinterCanvas.Font.PixelsPerInch:=GetDeviceCaps(Printer.Handle,LogPixelsX);
    PrinterCanvas.Font.Assign(stBodytextFont.Font);
  end;

begin
  Metafiles.Clear;
  MetaFile:=TMetaFile.Create;
  PrinterCanvas:=TMetaFileCanvas.Create(MetaFile,Printer.Handle);

  //
  ppmmx:=GetDeviceCaps(Printer.Handle,LogPixelsX) / 25.4;
  ppmmy:=GetDeviceCaps(Printer.Handle,LogPixelsY) / 25.4;
  PrinterCanvas.FillRect(Rect(0,0,GetDeviceCaps(Printer.Handle,PHYSICALWIDTH),GetDeviceCaps(Printer.Handle,PHYSICALHEIGHT)));
  PrinterCanvas.Font.PixelsPerInch:=GetDeviceCaps(Printer.Handle,LogPixelsX);
  PrintablePaper.Left:=Round(ppmmx*udLeftMargin.Position);
  PrintablePaper.Right:=Round(Printer.PageWidth - ppmmx*udRightMargin.Position);
  PrintablePaper.Top:=Round(ppmmy*udTopMargin.Position);
  PrintablePaper.Bottom:=Round(Printer.PageHeight - ppmmy*udBottomMargin.Position);
  // Title
  CurrentPos:=PrintablePaper.TopLeft;
  PrinterCanvas.Font.Assign(stHeaderFont.Font);
  PrinterCanvas.TextOut(CurrentPos.x,CurrentPos.y,'MLPA Analysis');
  CurrentPos.y:=CurrentPos.y+FontLineHeight;

  PrinterCanvas.Font.Assign(stBodytextFont.Font);
  XScale:=(FontLineHeight / frmMain.sgAnalyses.DefaultRowHeight) * (ppmmx / ppmmy);
  for arow:=0 to frmMain.sgAnalyses.RowCount-1 do
  begin
    if Currentpos.Y>(PrintablePaper.Bottom-FontLineheight) then
      AddMetafile;
    CurrentPos.x:=PrintablePaper.Left;
    PrinterCanvas.Brush.Color:=clWhite;
    for acol:=0 to frmMain.startdata-1 do
    begin
      PrinterCanvas.TextOut(CurrentPos.x,CurrentPos.y,frmMain.sgAnalyses.Cells[acol,arow]);
      CurrentPos.x:=CurrentPos.x+Round(XScale * frmMain.sgAnalyses.ColWidths[acol]);
    end;
    // use rest of paper for data
    datacellwidth:=(PrintablePaper.Right-CurrentPos.x) div frmMain.datalist.Count;
    CurrentCell.Top:=CurrentPos.y;
    CurrentCell.Bottom:=CurrentPos.y+FontLineHeight;
    for acol:=frmMain.startdata to frmMain.sgAnalyses.ColCount-1 do
    begin
      // draw colored rectangle
      CurrentCell.Left:=CurrentPos.x;
      CurrentCell.Right:=CurrentPos.x+datacellwidth;
      if arow>0 then
        PrinterCanvas.Brush.Color:=frmMain.GetAnalysisColor(acol-frmMain.startdata,arow-1,clWhite)
      else
        PrinterCanvas.Brush.Color:=clWhite;
      PrinterCanvas.FillRect(CurrentCell);
      PrinterCanvas.TextOut(CurrentPos.x,CurrentPos.y,frmMain.sgAnalyses.Cells[acol,arow]);
      CurrentPos.x:=CurrentPos.x+datacellwidth;
    end;
    CurrentPos.y:=CurrentPos.y+FontLineHeight; // linefeed
  end;

  // lblLinesNeeded.Caption:=IntToStr(CDOutput.LinesNeeded);

  AddMetafile;
  seCurrentPage.MaxValue:=Metafiles.Count;
  lblPageCount.Caption:='of '+IntToStr(Metafiles.Count);
end;

procedure TdlgPrintAnalysis.UpdatePreviewImage;
var
  SizeRatio : Real;
  PreviewRect:TRect;
  Metafile:TMetafile;
begin
  Metafile:=TMetafile(Metafiles[seCurrentPage.Value-1]);
  // Adapt ratio to metafile
  PreviewRect.Top:=bvlPreview.Top+PreviewMargin;
  PreviewRect.Left:=bvlPreview.Left+PreviewMargin;
  PreviewRect.Bottom:=bvlPreview.Height-(PreviewMargin*2);
  PreviewRect.Right:=bvlPreview.Width-(PreviewMargin*2);

  SizeRatio:=(Metafile.Width/Metafile.Height)/(PreviewRect.Right/PreviewRect.Bottom);
  If SizeRatio>1 then
  begin
    // Image area must be made less high
    imgPreview.Width:=PreviewRect.Right;
    imgPreview.Height:=Round(PreviewRect.Bottom / Sizeratio);
  end
  else begin
    // Image area must be made less wide
    imgPreview.Width:=Round(PreviewRect.Right * Sizeratio);
    imgPreview.Height:=PreviewRect.Bottom;
  end;
  // Center preview within bevel
  imgPreview.Left:=bvlPreview.Left+((bvlPreview.Width-imgPreview.Width) div 2);
  imgPreview.Top:=bvlPreview.Top+((bvlPreview.Height-imgPreview.Height) div 2);
  // Put metafile on screen paper
  imgPreview.Picture.Metafile:=MetaFile;
  // UpdateRectangle;
end;

procedure TdlgPrintAnalysis.btnPrinterSetupClick(Sender: TObject);
begin
  if dlgPrint.Execute then
  begin
    UpdatePreview;
  end;
end;

procedure TdlgPrintAnalysis.UpdatePreview;
begin
  UpdateMetafile;
  UpdatePreviewImage;
  lblPrinterName.Caption:=Printer.Printers[Printer.PrinterIndex];
  lblPageWidth.Caption:=IntToStr(GetDeviceCaps(Printer.Handle,HORZSIZE));
  lblPageHeight.Caption:=IntToStr(GetDeviceCaps(Printer.Handle,VERTSIZE));
  lblTopMargin.Caption:=IntToStr(udTopMargin.Position);
  lblBottomMargin.Caption:=IntToStr(udBottomMargin.Position);
  lblLeftMargin.Caption:=IntToStr(udLeftMargin.Position);
  lblRightMargin.Caption:=IntToStr(udRightMargin.Position);
end;

procedure TdlgPrintAnalysis.stHeaderFontClick(Sender: TObject);
begin
  dlgFont.Font.Assign(stHeaderFont.Font);
  if dlgFont.Execute then
  begin
    stHeaderFont.Font.Assign(dlgFont.Font);
    UpdatePreview;
  end;
end;

procedure TdlgPrintAnalysis.stBodytextFontClick(Sender: TObject);
begin
  dlgFont.Font.Assign(stBodytextFont.Font);
  if dlgFont.Execute then
  begin
    stBodytextFont.Font.Assign(dlgFont.Font);
    UpdatePreview;
  end;
end;

procedure TdlgPrintAnalysis.udTopMarginClick(Sender: TObject;
  Button: TUDBtnType);
begin
  UpdatePreview;
end;

procedure TdlgPrintAnalysis.seCurrentPageChange(Sender: TObject);
begin
  UpdatePreviewImage;
end;

end.
